//
//  LDXRequest.swift
//  RequestLib
//
//  Created by 刘东旭 on 2022/1/3.
//  Copyright © 2022 刘东旭. All rights reserved.
//

import Foundation

enum HTTPMethod: String {
    case GET
    case POST
}

protocol LDXRequestable {
    var urlString: String { get set }
    var method: HTTPMethod { get set }
    var parameters: Dictionary<String, Any>? { get set }
    var headers: Dictionary<String, Any>? { get set }
    func customRequest() -> URLRequest?
    func responseData(data: Data?, response: URLResponse?, error: Error?)
}

extension LDXRequestable {
    func start() -> Bool {
        var request: URLRequest? = customRequest()
        if request == nil {
            var param = ""
            if method == .GET {
                if parameters?.count ?? 0 > 0 {
                    param.append("?")
                }
                parameters?.forEach { (key, value) in
                    param.append(key)
                    param.append("=")
                    param.append("\(value)")
                }
            }
            guard let url = URL(string: urlString + param) else { return false }
            request = URLRequest(url: url)
            request?.httpMethod = method.rawValue
            if method == .POST {
                if parameters != nil {
                    request?.httpBody = try? JSONSerialization.data(withJSONObject: parameters!, options: [])
                }
            }
            headers?.forEach { (key, value) in
                request?.addValue("\(value)", forHTTPHeaderField: key)
            }
        }
        guard let req = request else { return false }
        let task = URLSession.shared.dataTask(with: req, completionHandler: { data, resp, error in
            responseData(data: data, response: resp, error: error)
        })
        task.resume()
        return true
    }
}

struct ApiRequest: LDXRequestable {
    
    var urlString: String
    
    var method: HTTPMethod
    
    var parameters: Dictionary<String, Any>?
    
    var headers: Dictionary<String, Any>?
    
    var successCallBack: (Any) -> Void?
    
    var failureCallBack: (Error) -> Void?
    
    func customRequest() -> URLRequest? {
        return nil
    }
    
    struct LDXError: Error {
        var desc: String = ""
        init(_ desc: String) {
            self.desc = desc
        }
    }
    
//    func customParseResponseData(data: Data?) -> Dictionary<String, Any>? {
//        var jsonData = data
//        jsonData!.removeFirst()
//        jsonData!.removeLast()
//        jsonData!.removeLast()
//        guard let obj = try? JSONSerialization.jsonObject(with: jsonData!, options: [.mutableLeaves,.mutableContainers]) as? [String:Any] else {
//            return nil
//        }
//        return obj
//    }
    
    func responseData(data: Data?, response: URLResponse?, error: Error?) {
        if error != nil {
            failureCallBack(error!)
            return
        }
        guard let d = data else { return }
        guard let obj = try? JSONSerialization.jsonObject(with: d, options: [.mutableLeaves,.mutableContainers]) as? [String:Any] else {
            let err = LDXError("序列化失败！")
            failureCallBack(err)
            return
        }
        successCallBack(obj)
    }
}
